home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 38 / Amiga Format CD38 (1999-03-15)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-04].iso / -seriously_amiga- / programming / other / cyberxxxsrc / decoder / txt / decodesmc.c < prev    next >
C/C++ Source or Header  |  1999-02-08  |  8KB  |  332 lines

  1. /*
  2. sc:c/sc opt txt/DecodeSMC.c
  3. */
  4.  
  5. #include "Decode.h"
  6.  
  7. #define smcMaxCnt 256
  8.  
  9. struct SMCData {
  10.   ulong smc8[2*smcMaxCnt];
  11.   ulong smcA[4*smcMaxCnt];
  12.   ulong smcC[8*smcMaxCnt];
  13. };
  14.  
  15. /* /// "blockInc" */
  16. #define blockInc(x,y,xmax) { \
  17.                       x+=4; \
  18.                       if (x>=xmax) { \
  19.                         x=0; \
  20.                         y+=4; \
  21.                       } \
  22.                    }
  23. /* \\\ */
  24.  
  25. /* /// "smcO2I" */
  26. #define smcO2I(ip,op,rInc) {                                              \
  27.   ip[0]=op[0]; ip[1]=op[1]; ip[2]=op[2]; ip[3]=op[3]; ip+=rInc; op+=rInc; \
  28.   ip[0]=op[0]; ip[1]=op[1]; ip[2]=op[2]; ip[3]=op[3]; ip+=rInc; op+=rInc; \
  29.   ip[0]=op[0]; ip[1]=op[1]; ip[2]=op[2]; ip[3]=op[3]; ip+=rInc; op+=rInc; \
  30.   ip[0]=op[0]; ip[1]=op[1]; ip[2]=op[2]; ip[3]=op[3];                     \
  31. }
  32. /* \\\ */
  33.  
  34. /* /// "smcC1" */
  35. #define smcC1(ip,c,rInc) {                      \
  36.   ip[0]=c; ip[1]=c; ip[2]=c; ip[3]=c; ip+=rInc; \
  37.   ip[0]=c; ip[1]=c; ip[2]=c; ip[3]=c; ip+=rInc; \
  38.   ip[0]=c; ip[1]=c; ip[2]=c; ip[3]=c; ip+=rInc; \
  39.   ip[0]=c; ip[1]=c; ip[2]=c; ip[3]=c; ip+=rInc; \
  40. }
  41. /* \\\ */
  42.  
  43. /* /// "smcC2" */
  44. #define smcC2(ip,c0,c1,mask,rInc) { \
  45.   ip[0]=(mask & 0x80) ? c1 : c0;    \
  46.   ip[1]=(mask & 0x40) ? c1 : c0;    \
  47.   ip[2]=(mask & 0x20) ? c1 : c0;    \
  48.   ip[3]=(mask & 0x10) ? c1 : c0;    \
  49.   ip+=rInc;                         \
  50.   ip[0]=(mask & 0x08) ? c1 : c0;    \
  51.   ip[1]=(mask & 0x04) ? c1 : c0;    \
  52.   ip[2]=(mask & 0x02) ? c1 : c0;    \
  53.   ip[3]=(mask & 0x01) ? c1 : c0;    \
  54. }
  55. /* \\\ */
  56.  
  57. /* /// "smcC4" */
  58. #define smcC4(ip,c,maskA,maskB,rInc) { \
  59.   ip[0]=c[(maskA>>6) & 0x03];          \
  60.   ip[1]=c[(maskA>>4) & 0x03];          \
  61.   ip[2]=c[(maskA>>2) & 0x03];          \
  62.   ip[3]=c[ maskA     & 0x03];          \
  63.   ip+=rInc;                            \
  64.   ip[0]=c[(maskB>>6) & 0x03];          \
  65.   ip[1]=c[(maskB>>4) & 0x03];          \
  66.   ip[2]=c[(maskB>>2) & 0x03];          \
  67.   ip[3]=c[ maskB     & 0x03];          \
  68. }
  69. /* \\\ */
  70.  
  71. /* /// "smcC8" */
  72. #define smcC8(ip,c,mask,rInc) { \
  73.   ip[0]=c[(mask>>21) & 0x07];   \
  74.   ip[1]=c[(mask>>18) & 0x07];   \
  75.   ip[2]=c[(mask>>15) & 0x07];   \
  76.   ip[3]=c[(mask>>12) & 0x07];   \
  77.   ip+=rInc;                     \
  78.   ip[0]=c[(mask>> 9) & 0x07];   \
  79.   ip[1]=c[(mask>> 6) & 0x07];   \
  80.   ip[2]=c[(mask>> 3) & 0x07];   \
  81.   ip[3]=c[ mask      & 0x07];   \
  82. }
  83. /* \\\ */
  84.  
  85. /* /// "smcC16" */
  86. #define smcC16(ip,dp) { \
  87.   ip[0]=dp[0];          \
  88.   ip[1]=dp[1];          \
  89.   ip[2]=dp[2];          \
  90.   ip[3]=dp[3];          \
  91. }
  92. /* \\\ */
  93.  
  94. /* /// "DecodeSMC()" */
  95. __asm void DecodeSMC(REG(a0) uchar *from,
  96.                      REG(a1) uchar *to,
  97.                      REG(d0) ulong width,
  98.                      REG(d1) ulong height,
  99.                      REG(d2) ulong encSize,
  100.                      REG(a2) struct SMCData *spec)
  101. {
  102.   long x, y, len, rowInc;
  103.   ulong i, cnt, hiCode, code, *c;
  104.   ulong smc8Cnt, smcACnt, smcCCnt;
  105.  
  106.   smc8Cnt=0;
  107.   smcACnt=0;
  108.   smcCCnt=0;
  109.   x=0;
  110.   y=0;
  111.   rowInc=width;
  112.  
  113.   from++;
  114.   len=get24(from);
  115.   len-=4;
  116.   while (len>0) {
  117.     code=*from++;
  118.     hiCode=code & 0xf0;
  119.     code=(code & 0x0f)+1;
  120.     len--;
  121.     switch (hiCode) {
  122.       case 0x00:
  123.       case 0x10:
  124.         {
  125.           if (hiCode==0x10) {
  126.             cnt=*from++;
  127.             cnt++;
  128.             len--;
  129.           } else {
  130.             cnt=code;
  131.           }
  132.           while (cnt--) blockInc(x,y,width);
  133.         }
  134.         break;
  135.  
  136.       case 0x20:
  137.       case 0x30:
  138.         {
  139.           ulong tx, ty;
  140.           uchar *op;
  141.           if (hiCode==0x30) {
  142.             cnt=*from++;
  143.             cnt++;
  144.             len--;
  145.           } else {
  146.             cnt=code;
  147.           }
  148.           if (x==0) {
  149.             ty=y-4;
  150.             tx=width-4;
  151.           } else {
  152.             ty=y;
  153.             tx=x-4;
  154.           }
  155.           op=to+(ty*width+tx);
  156.           while (cnt--) {
  157.             uchar *iptr=to+(y*width+x);
  158.             uchar *optr=op;
  159.             smcO2I(iptr,optr,rowInc);
  160.             blockInc(x,y,width);
  161.           }
  162.         }
  163.         break;
  164.  
  165.       case 0x40:
  166.       case 0x50:
  167.         {
  168.           ulong cnt, cnt1;
  169.           long mtx, mty, tx, ty;
  170.           if (hiCode==0x50) {
  171.             cnt1=*from++;
  172.             cnt1++;
  173.             len--;
  174.           } else {
  175.             cnt1=code;
  176.           }
  177.           mtx=x-8;
  178.           mty=y;
  179.           if (mtx<0) {
  180.             mtx+=width;
  181.             mty-=4;
  182.           }
  183.           while (cnt1--) {
  184.             uchar *iptr, *optr;
  185.             cnt=2;
  186.             tx=mtx;
  187.             ty=mty;
  188.             while (cnt--) {
  189.               iptr=to+(y*width+x);
  190.               optr=to+(ty*width+tx);
  191.               smcO2I(iptr,optr,rowInc);
  192.               blockInc(x,y,width);
  193.               blockInc(tx,ty,width);
  194.             }
  195.           }
  196.         }
  197.         break;
  198.  
  199.       case 0x60:
  200.       case 0x70:
  201.         {
  202.           ulong ct, cnt;
  203.           if (hiCode==0x70) {
  204.             cnt=*from++;
  205.             cnt++;
  206.             len--;
  207.           } else {
  208.             cnt=code;
  209.           }
  210.           ct=*from++;
  211.           len--;
  212.           while (cnt--) {
  213.             uchar *iptr=to+(y*width+x);
  214.             smcC1(iptr,ct,rowInc);
  215.             blockInc(x,y,width);
  216.           }
  217.         }
  218.         break;
  219.  
  220.       case 0x80:
  221.       case 0x90:
  222.         {
  223.           ulong cnt=code;
  224.           if (hiCode==0x80) {
  225.             c=&spec->smc8[smc8Cnt<<1];
  226.             smc8Cnt++;
  227.             if (smc8Cnt==smcMaxCnt) smc8Cnt=0;
  228.             for (i=0; i<2; i++) c[i]=*from++;
  229.             len-=2;
  230.           } else {
  231.             c=&spec->smc8[(*from++)<<1];
  232.             len--;
  233.           }
  234.           while (cnt--) {
  235.             ulong mask0, mask1;
  236.             uchar *iptr=to+(y*width+x);
  237.             mask0=from[0];
  238.             mask1=from[1];
  239.             from+=2;
  240.             len-=2;
  241.             smcC2(iptr,c[0],c[1],mask0,rowInc); iptr+=rowInc;
  242.             smcC2(iptr,c[0],c[1],mask1,rowInc);
  243.             blockInc(x,y,width);
  244.           }
  245.         }
  246.         break;
  247.  
  248.       case 0xa0:
  249.       case 0xb0:
  250.         {
  251.           ulong cnt=code;
  252.           if (hiCode==0xa0) {
  253.             c=&spec->smcA[smcACnt<<2];
  254.             smcACnt++;
  255.             if (smcACnt==smcMaxCnt) smcACnt=0;
  256.             for (i=0; i<4; i++) c[i]=*from++;
  257.             len-=4;
  258.           } else {
  259.             c=&spec->smcA[(*from++)<<2];
  260.             len--;
  261.           }
  262.           while (cnt--) {
  263.             ulong mask0, mask1, mask2, mask3;
  264.             uchar *iptr=to+(y*width+x);
  265.             mask0=from[0];
  266.             mask1=from[1];
  267.             mask2=from[2];
  268.             mask3=from[3];
  269.             from+=4;
  270.             len-=4;
  271.             smcC4(iptr,c,mask0,mask1,rowInc); iptr+=rowInc;
  272.             smcC4(iptr,c,mask2,mask3,rowInc);
  273.             blockInc(x,y,width);
  274.           }
  275.         }
  276.         break;
  277.  
  278.       case 0xc0:
  279.       case 0xd0:
  280.         {
  281.           ulong cnt=code;
  282.           if (hiCode==0xc0) {
  283.             c=&spec->smcC[smcCCnt<<3];
  284.             smcCCnt++;
  285.             if (smcCCnt==smcMaxCnt) smcCCnt=0;
  286.             for (i=0; i<8; i++) c[i]=*from++;
  287.             len-=8;
  288.           } else {
  289.             c=&spec->smcC[(*from++)<<3];
  290.             len--;
  291.           }
  292.           while (cnt--) {
  293.             ulong t, mBits0, mBits1;
  294.             uchar *iptr=to+(y*width+x);
  295.             t=get16(from);
  296.             mBits0=(t & 0xfff0)<<8;
  297.             mBits1=(t & 0x000f)<<8;
  298.             t=get16(from);
  299.             mBits0|=(t & 0xfff0)>>4;
  300.             mBits1|=(t & 0x000f)<<4;
  301.             t=get16(from);
  302.             mBits1|=(t & 0xfff0)<<8;
  303.             mBits1|=(t & 0x000f);
  304.             len-=6;
  305.             smcC8(iptr,c,mBits0,rowInc); iptr+=rowInc;
  306.             smcC8(iptr,c,mBits1,rowInc);
  307.             blockInc(x,y,width);
  308.           }
  309.         }
  310.         break;
  311.  
  312.       case 0xe0:
  313.         {
  314.           ulong cnt=code;
  315.           while (cnt--) {
  316.             uchar *iptr=to+(y*width+x);
  317.             smcC16(iptr,from); iptr+=rowInc; from+=4;
  318.             smcC16(iptr,from); iptr+=rowInc; from+=4;
  319.             smcC16(iptr,from); iptr+=rowInc; from+=4;
  320.             smcC16(iptr,from); iptr+=rowInc; from+=4;
  321.             len-=16;
  322.             blockInc(x,y,width);
  323.           }
  324.         }
  325.         break;
  326.       default: break;
  327.     }
  328.   }
  329. }
  330. /* \\\ */
  331.  
  332.